/** * @description : 统计页面swiper组件 * @descriptionDetail : 统计页面swiper组件 * @copyright : 浙江烟草 * @author : mc * @create : 2022-12-05 13:57:01 */
<template>
  <swiper
    :style="{ 'height': height + 'px', }"
    :indicator-dots="header.length > 0"
    indicator-color="rgba(0,0,0,0.3)"
    indicator-active-color="#2979FF"
    :autoplay="autoplay"
    :interval="interval"
    :duration="duration"
    :current="current"
    @change="swiperChange"
  >
    <swiper-item class="swiper-item" v-if="header.length == 0">
      <u-empty text="没有数据" mode="list"></u-empty>
    </swiper-item>
    <template v-else>
      <swiper-item class="swiper-item" v-for="(item, index) in header" :key="'swiperItem' + index">
        <view class="head-row">
          <u-row gutter="8" style="flex: 1">
            <u-col :span="sItem.columnSpan || 3" v-for="(sItem, sIndex) in item" :key="'col' + index + sIndex">
              <view
                class="head-title-lay"
                @tap="handleSort(sItem)"
                :style="{
                  textAlign: sItem.align || 'center',
                  paddingRight: (sIndex == item.length - 1) ? '10rpx' : '0px',
                  justifyContent: (!sItem.align || sItem.align == 'center') ? 'center' : (sItem.align == 'right' ? 'flex-end' : 'flex-start'),
                }"
              >
                <view class="split-title" style="font-size: 15px">
                  {{ sItem.label }}
                </view>
                <view class="sort-icon" v-if="sItem.hasSort">
                  <!-- {{ sItem.label }} {{ ifLabel }} -->
                  <u-icon
                    :size="22"
                    :color=" sItem.label != ifLabel ? '#bfbfbf' : (sortKeys[sItem.fieldKey] == 'asc' ? '#333' : '#bfbfbf')"
                    name="arrow-up-fill"
                  ></u-icon>
                  <u-icon
                    :size="22"
                    :color="sItem.label != ifLabel ? '#bfbfbf' :(sortKeys[sItem.fieldKey] == 'desc' ? '#333' : '#bfbfbf')"
                    name="arrow-down-fill"
                  ></u-icon>
                </view>
              </view>
            </u-col>
          </u-row>
        </view>
        <template v-if="content && content.length == 0 && (hasTotalRow && $u.test.isEmpty(realTotalRow))">
          <u-empty text="没有数据" mode="search"></u-empty>
        </template>
        <template v-else>
          <scroll-view
            :scroll-top="0" :style="{ height: getScrollHeight() }" :scroll-y="true"
            :scroll-x="false" class="scroll-Y table-body"
          >
            <!-- 合计 -->
            <template v-if="hasTotalRow && realTotalRow">
              <u-row gutter="20" class="row-item total-row-lay" style="background-color: #f7f7f7 !important">
                <u-col :span="tItem.columnSpan || 3" v-for="(tItem, tIndex) in item" :key="'colcontentTotal' + index + tIndex">
                  <view
                    class="list-item split-total"
                    :style="{
                      paddingRight: (tIndex == item.length - 1) ? '10rpx' : '0px',
                      textAlign: tIndex == 0 ? 'center' : (tItem.align || 'center'),
                      justifyContent: (tIndex == 0 || !tItem.align || tItem.align == 'center') ? 'center' : (tItem.align == 'right' ? 'flex-end' : 'flex-start'),
                      color: contentColor(realTotalRow[tItem.fieldKey])
                    }"
                  >
                    {{ tIndex == 0 ? getTotalRealTitle(tItem.unit) : filterNum(realTotalRow[tItem.fieldKey]) }}
                  </view>
                </u-col>
              </u-row>
            </template>
            <u-row
              v-for="(rowItem, rowIndex) in content"
              :key="'rowContent' + index + rowIndex"
              @click.native="handleDoubleClick(rowItem)"
              :class="'row-item row-lay ' + (itemKeyUuid === rowItem[keyCode] ? 'taped-item' : '')"
              gutter="20"
              :needTapHover="true"
            >
              <u-col
                v-for="(cItem, cIndex) in item"
                :key="'colcontent' + index + rowIndex + cIndex"
                @tap="cIndex === 0 && handleTapListItem(rowItem, rowIndex)"
                :span="cItem.columnSpan || 3"
              >
                <view
                  class="list-item split-val"
                  :style="{
                    paddingRight: (cIndex == item.length - 1) ? '10rpx' : '0px',
                    textAlign: cItem.align || 'center',
                    justifyContent: (!cItem.align || cItem.align == 'center') ? 'center' : (cItem.align == 'right' ? 'flex-end' : 'flex-start'),
                    color: contentColor(rowItem[cItem.fieldKey])
                  }"
                >
                  {{ filterNum(rowItem[cItem.fieldKey])}}
                </view>
              </u-col>
            </u-row>

          </scroll-view>
        </template>
      </swiper-item>

    </template>
  </swiper>

</template>

<script>
Number.prototype.toFixedNo = function (fixed) {
  let num = this;
  // 默认保留小数
  fixed = fixed || 0;
  // 如果fixed不是数字，直接返回
  if (isNaN(fixed)) {
    return num.toString();
  } else {
    let numStr = num.toString();
    // 如果num不是小数，返回
    if (numStr.indexOf('.') < 0 || numStr.indexOf('.') == numStr.length - 1) {
      return parseInt(num);
    } else if (fixed == 0) {
      let arr = numStr.split('.');
      let integer = arr[0];
      let decimals = arr[1];
      if (parseInt(decimals) != 0) {
        if (decimals.substr(0, 1) >= 5) {
          integer = parseInt(integer) + 1;
        }
      }
      return integer;
    } else {
      let arr = numStr.split('.');
      let integer = arr[0];
      let decimals = arr[1];

      if (fixed < decimals.length) {
        let fixedNo = decimals.substr(0, fixed);
        //  判断保留位的下一位是否大于5，四舍五入
        if (decimals.substr(fixed, 1) >= 5) {
          fixedNo = parseInt(fixedNo) + 1;
        } else {
          if (parseInt(fixedNo) == 0) {
            return integer;
          }
          // 移除多余的0
          fixedNo = fixedNo.replace(/0+$/, '');
        }
        1;
        decimals = fixedNo;
      }
      return integer + '.' + decimals;
    }
  }
};
export default {
  name: 'SwiperStatsCom',
  props: {
    autoplay: {
      // 是否自动切换
      type: Boolean,
      default: false,
    },
    interval: {
      // 自动切换时间间隔
      type: Number,
      default: 5000,
    },
    duration: {
      // 滑动动画时长
      type: Number,
      default: 500,
    },
    // current: { // 当前所在滑块的 index
    //   type: Number,
    //   default: 0,
    // },
    height: {
      // 高度
      type: Number,
      default: 500,
    },
    keyCode: {
      // 唯一主键标识
      type: String,
      default: '',
    },
    itemKeyUuid: {
      type: String,
      default: '',
    },
    hasTotalRow: {
      type: Boolean,
      default: true,
    },
    needCalcTotal: {
      type: Boolean,
      default: false,
    },
    totalTitle: {
      type: String,
      default: '合计',
    },
    totalEndOrStart: {
      // needCalcTotal 为false 表示total数据在源数据中，则要给出源数据中total行所在索引 true 表示 0  false 表示 最后一行
      type: Boolean,
      default: true,
    },
    orginalData: {
      // 原始数据
      type: Object,
      default: () => {
        return {
          header: [],
          content: [],
        };
      },
    },
    fixedLimit: {
      type: Number,
      default: 2,
    },
    normalTxtColor: {
      type: String,
      default: '#393B3D',
    },
    errorTxtColor: {
      type: String,
      default: '#fa3534',
    },
    areaKey: {
      type: String,
      default: 'orgName',
    },
  },
  data() {
    return {
      header: [], // 二维数组 单个对象{ label:"", fieldKey:"", sort: "",columnSpan: 2,hasSort : false ,ext:{}, } // sort : asc, desc
      content: [], // 单个对象{} ,
      realTotalRow: {}, // 统计行数据
      sortKeys: {}, // 排序相关字段
      dbStartTime: 0, // 双击开始时间
      dbEndTime: 0, // 双击结束时间
      dbIndex: 0, // 双击标识
      current: 0,
      ifLabel: '',
    };
  },
  computed: {},
  watch: {
    orginalData: {
      handler(newVal, oldVal) {
        this.initStatus(newVal);
      },
      deep: true,
      immediate: true,
    },
  },
  methods: {
    initStatus(obj) {
      this.header = this.$u.deepClone(obj.header) || [];
      this.current = 0;
      this.content = this.$u.deepClone(obj.content) || [];
      this.realTotalRow = {};
      this.sortKeys = {};
      if (this.content.length == 0 || this.header.length == 0) return;
      if (this.needCalcTotal) {
        this.realTotalRow = {};
        for (let i = 0; i < this.header.length; i++) {
          let item = this.header[i];
          for (let j = 0; j < item.length; j++) {
            let op = item[j];
            if (!op.hasSort) {
              this.$set(this.realTotalRow, op.fieldKey, this.totalTitle);
              continue;
            }
            let opVal = 0;
            for (let x = 0; x < this.content.length; x++) {
              opVal += this.getNum(op.fieldKey, this.content[x]);
            }
            this.$set(this.realTotalRow, op.fieldKey, opVal.toFixedNo(this.fixedLimit));
          }
        }
        console.log(this.realTotalRow);
      } else {
        let tmp = this.content.splice(this.totalEndOrStart ? 0 : this.content.length - 1, 1);
        if (tmp && tmp.length > 0) {
          this.realTotalRow = tmp[0];
        }
      }
    },
    getScrollHeight() {
      let p = this.height - uni.upx2px(80) + 'px';
      // #ifdef H5-WECHAT
      p = this.height + 'px';
      // #endif
      return p;
    },
    swiperChange(e) {
			this.current = e.detail.current;

    },
    getTotalRealTitle(unit) {
      return `${this.totalTitle}(${unit})`;
    },
    getNum(key, obj) {
      let n;
      try {
        n = Number(obj[key]);
      } catch (e) {
        n = 0;
      }
      if (isNaN(n)) n = 0;
      return n;
    },
    filterNum(n) {
      let m = n;
      if (typeof m == 'string') {
        m = Number(m);
        if (isNaN(m)) {
          m = n;
        }
      }
      if (typeof m == 'number' && !isNaN(m) && m != 0) {
        return m.toFixedNo(this.fixedLimit);
      }
      return m;
    },
    handleSort(itm) {
      this.ifLabel = itm.label;
      console.log(itm, 'itm');
      let tp = this.sortKeys[itm.fieldKey];
      this.sortKeys[itm.fieldKey] = tp == 'asc' ? 'desc' : 'asc';
      console.log(this.sortKeys[itm.fieldKey], '000');
      this.content.sort((it1, it2) => {
        let num1 = 0;
        let num2 = 0;
        try {
          num1 = Number(it1[itm.fieldKey]);
          num2 = Number(it2[itm.fieldKey]);
        } catch (e) {
          num1 = 0;
          num2 = 0;
          console.log(e);
        }
        if (this.sortKeys[itm.fieldKey] == 'asc') {
          return num1 - num2;
        } else {
          return num2 - num1;
        }
      });
    },
    contentColor(n) {
      let m = n;
      if (typeof m == 'string') {
        m = Number(m);
      }
      if (typeof m == 'number' && !isNaN(m)) {
        return m >= 0 ? this.normalTxtColor : this.errorTxtColor;
      }
      return this.normalTxtColor;
    },
    // 双击查看详情
    handleDoubleClick(obj) {
      this.dbIndex = this.dbIndex == 0 ? 1 : this.dbIndex + 1;
      if (this.dbIndex == 1) {
        this.dbStartTime = new Date().getTime();
        setTimeout(() => {
          this.dbIndex = this.dbStartTime = this.dbEndTime = 0;
        }, 200);
      } else if (this.dbIndex == 2) {
        this.dbEndTime = new Date().getTime();
        if (this.dbEndTime - this.dbStartTime < 300) {
          this.$emit('dbClick', obj);
        }
        this.dbIndex = this.dbStartTime = this.dbEndTime = 0;
      }
    },
    handleTapListItem(item, idx) {
      // 如果当前页是区域，则触发点击事件
      if (!this.$u.test.isEmpty(this.keyCode)) {
        // 如果用户是首次点击，则提示操作说明
        if (!this.$storage.get('IS_NOT_FIRST_ALERT')) {
          this.$modal.confirm(
            '您当前点击了【' + item[this.areaKey] + '】,切换“品规”或“经营业态”将展示【' + item[this.areaKey] + '】的数据，如果是误操作请点击右上角【刷新】',
            '操作提示',
            () => {
              this.$storage.set('IS_NOT_FIRST_ALERT', 1);
            },
            null,
            '不再提示',
            '关闭'
          );
        }
        this.$emit('clickItem', item, this.keyCode);
      }
    },
  },
};
</script>

<style scoped lang="scss">
	.slide-header-lay {
	}

	.head-row {
		height: 80rpx;
		width: 100%;
		background: #e0f1ff;
		display: flex;
		flex-direction: row;
		align-items: center;

		.u-row {
			height: inherit;
		}
	}

	.head-title-lay {
		display: flex;
		flex-direction: row;
		justify-content: center;
		align-items: center;
		width: 100%;
	}

	.sort-icon {
		display: grid;
		height: 20px;
		margin-left: 3px;
		font-size: 10px;
		transform: scale(0.6);
	}

	.split-title {
		color: #393b3d;
		font-weight: 600;
		font-size: 25rpx;
		word-break: keep-all;
		text-overflow: ellipsis;
	}

	.list-item {
		font-size: 26rpx;
		font-weight: 400;
		color: #393b3d;
		word-break: break-word;
	}

	.row-item {
		min-height: 84rpx;
		padding-top: 10rpx;
		padding-bottom: 10rpx;
	}

	.row-item:nth-child(odd) {
		// 双行
		background-color: white;
	}

	.row-item:nth-child(even) {
		//单行
		background-color: #fcfcfc;
		border-bottom: 1px solid #dfe0e1 !important;
		border-top: 1px solid #dfe0e1 !important;
	}

	.total-row-lay {
	}

	.row-lay:first-child {
    margin-top: 84rpx;
	}

	.taped-item {
		background-color: #e6e6e6 !important;
		font-weight: 600;
	}
</style>
